package org.ielts.action;

import static com.yifeng.struts2.ResultConstants.*;
import static com.yifeng.struts2.ResultParameters.setJson;
import static com.yifeng.struts2.ActionUtils.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.ielts.domain.LearnStatus;
import org.ielts.domain.base.Course;
import org.ielts.domain.base.SignCourse;
import org.ielts.domain.base.Student;
import org.ielts.domain.log.ConsultLog;
import org.ielts.domain.log.SignCourseLog;
import org.ielts.domain.report.ConsultantSignedReport;
import org.ielts.domain.report.StudentQuery;
import org.ielts.domain.security.User;
import org.ielts.service.ConsultantService;
import org.ielts.service.CourseService;
import org.ielts.service.SignCourseLogService;
import org.ielts.service.SignCourseService;
import org.ielts.service.StudentService;
import org.ielts.service.TutorService;
import org.ielts.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.ValidationUtils;
import com.yifeng.TimePair;
import com.yifeng.dto.FormRow;
import com.yifeng.modules.annotations.Operation;
import com.yifeng.web.Paginations;
import com.yifeng.sequence.ISeqService;
import com.yifeng.utils.JsonResultBuilder;
import com.yifeng.utils.PageUtils;
import com.yifeng.web.Pagers;

public class ConsultAction extends BaseAction {

	@Operation(result = FILL)
	public String preConsultVisit() {
		String no = form.readString("no");
		if (StringUtils.isNotBlank(no)) {
			Student student = studentService.findByNo(no);
			ArrayList<Student> students = new ArrayList<Student>(1);
			students.add(student);

			put("students", students);
		} else {
			String name = form.readString("name");
			if (StringUtils.isNotBlank(name)) {
				Iterable<Student> students = studentService.findByName(name);
				put("students", students);
			}
		}

		return FILL;
	}

	@Operation(result = FILL)
	public String consultVisit() {
		String id = form.readString("id");

		Student student = studentService.findOne(id);
		put("student", student);

		Iterable<Course> courses = courseService.findAll();
		put("courses", courses);

		return FILL;
	}

	@Operation(result = JSON)
	public String doConsultVisit() {
		String id = form.readString("id");
		String source = form.readString("source");
		String title = form.readString("title");
		String courseId = form.readString("courseId");

		ConsultLog consultLog = consultantService.consult(id, source, title, courseId);
		Student student = consultLog.getStudent();

		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "courses", "consultStatus", "consultor", "roles" });

		JSONObject jsonObject = JSONObject.fromObject(student, jsonConfig);

		setJson(JsonResultBuilder.success(true).msg("提交成功").add("student", jsonObject).json());

		return JSON;
	}

	@Autowired
	CourseService courseService;

	@Operation(result = FILL, operationText = "客户注册课程")
	public String preSignUp() {
		Iterable<Student> students = null;

		String stuId = form.readString("stuId");
		if (StringUtils.isNotBlank(stuId)) {
			stuId = stuId.trim();
			students = studentService.findByStuId(stuId);
		}

		String name = form.readString("name");
		if (StringUtils.isNotBlank(name)) {
			students = studentService.findByName(name);
		}

		put("students", students);

		return FILL;
	}

	@Operation(result = FILL, operationText = "客户注册课程")
	public String signUp() {
		String id = form.readString("id");

		Student student = studentService.findOne(id);
		put("student", student);

		Iterable<Course> courses = courseService.findAll();
		put("courses", courses);

		Iterable<User> consultants = consultantService.listConsultant();
		put("consultants", consultants);

		put("begin", DateUtil.getAsString(DateUtil.now(), "yyyy-MM-dd"));
		put("end", DateUtil.getAsString(DateUtil.nextYear(), "yyyy-MM-dd"));

		return FILL;
	}

	@Operation(result = JSON, operationText = "客户注册课程")
	public String doSignUp() {
		String id = form.readString("id");
		String courseId = form.readString("courseId");
		String contractId = form.readString("contractId");
		String cardId = form.readString("cardId");
		String term = form.readString("term");
		int times = valueReader.name("times").intValue();

		String consultantId = form.readString("consultantId");

		Date beginTime = valueReader.name("beginTime").dateValue("yyyy-MM-dd");
		Date endTime = valueReader.name("endTime").dateValue("yyyy-MM-dd");

		SignCourseLog signCourseLog = consultantService.signUp(id, courseId, consultantId, contractId, cardId, term,
				times, beginTime, endTime);

		Student student = signCourseLog.getStudent();

		setJson(JsonResultBuilder.success(true).msg("提交成功").add("student", student).json());
		return JSON;
	}

	@Autowired
	SignCourseService signCourseService;

	@Operation(result = "FILL")
	public String listCourseRemainTimes() {
		Iterable<User> consultants = consultantService.listConsultant();
		put("consultants", consultants);

		StudentQuery studentQuery = new StudentQuery();
		// 咨询师关注
		String[] consultStarred = form.readStrings("consultStarred");
		if (consultStarred.length > 0) {
			boolean[] consultStarreds = new boolean[consultStarred.length];

			for (int i = 0; i < consultStarreds.length; i++) {
				boolean starred = consultStarred[i].equals("true") ? true : false;
				consultStarreds[i] = starred;
			}

			studentQuery.addConsultStarred(consultStarreds);
		}
		String[] consultant = form.readStrings("consultant");
		// 咨询师筛选
		if (consultant.length > 0) {
			studentQuery.addConsultant(consultant);
		}

		Pageable pageable = getPageable();

		int remainTimes = valueReader.name("times").defaultValue(20).intValue();

		put("times", remainTimes);

		Page<SignCourse> signCourses = signCourseService.findByRemainTimes(studentQuery, remainTimes, pageable);

		put("signCourses", signCourses);
		put(PAGINATIONS, new Paginations(signCourses));
		return FILL;
	}

	@Operation(result = "FILL")
	public String listCourseRemainDate() {
		Iterable<User> consultants = consultantService.listConsultant();
		put("consultants", consultants);

		StudentQuery studentQuery = new StudentQuery();
		// 咨询师关注
		String[] consultStarred = form.readStrings("consultStarred");
		if (consultStarred.length > 0) {
			boolean[] consultStarreds = new boolean[consultStarred.length];

			for (int i = 0; i < consultStarreds.length; i++) {
				boolean starred = consultStarred[i].equals("true") ? true : false;
				consultStarreds[i] = starred;
			}

			studentQuery.addConsultStarred(consultStarreds);
		}
		String[] consultant = form.readStrings("consultant");
		// 咨询师筛选
		if (consultant.length > 0) {
			studentQuery.addConsultant(consultant);
		}

		Pageable pageable = getPageable();

		Date now = new Date();
		Date defaultTime = DateUtils.addDays(now, 7);
		defaultTime = DateUtils.truncate(defaultTime, Calendar.DATE);

		Date endTime = valueReader.name("endTime").defaultValue(defaultTime).dateValue("yyyy-MM-dd");

		put("endTime", endTime);

		Page<SignCourse> signCourses = signCourseService.findByRemainDate(studentQuery, endTime, pageable);

		put("signCourses", signCourses);

		put(PAGINATIONS, new Paginations(signCourses));
		return FILL;
	}

	@Autowired
	TutorService tutorService;

	@Operation(result = FILL, operationText = "列出分配给我的学员")
	public String listMyStudent() {
		Iterable<User> tutors = tutorService.listTutor();
		put("tutors", tutors);

		Iterable<Course> courses = courseService.findAll();
		put("courses", courses);

		String myid = profile.getUserId();

		StudentQuery studentQuery = buildStudentQuery(form);
		studentQuery.addConsultant(new String[] { myid });

		StringBuilder sb = buildSearchString(studentQuery, tutors, courses);
		put("search", sb);

		Pageable pageable = getPageable();
		Page<Student> students = studentService.findAll(studentQuery, pageable);

		put("students", students);
		put(PAGINATIONS, new Paginations(students));
		return FILL;
	}

	private Course findCourse(Iterable<Course> courses, String courseId) {
		for (Course course : courses) {
			if (course.getId().equals(courseId)) {
				return course;
			}
		}

		return new Course();
	}

	private StringBuilder buildSearchString(StudentQuery studentQuery, Iterable<User> tutors, Iterable<Course> courses) {
		StringBuilder sb = new StringBuilder();

		if (studentQuery.hasConsultStarred()) {
			if (studentQuery.getConsultStarred().length != 2) {
				if (studentQuery.getConsultStarred()[0]) {
					sb.append("在咨询中，");
				} else {
					sb.append("不在咨询中，");
				}
			}
		}

		if (studentQuery.hasCourse()) {
			sb.append("注册了");

			for (String courseId : studentQuery.getCourse()) {
				Course c = findCourse(courses, courseId);

				sb.append("<strong>");
				sb.append(c.getName());
				sb.append("</strong>");

				sb.append(",");
			}

			sb.setLength(sb.length() - 1);
			sb.append("课程，");
		}

		if (studentQuery.hasCourseDate()) {
			sb.append("开课时间：");
			sb.append("<strong>");
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
			sb.append(simpleDateFormat.format(studentQuery.getCourseDate().getStartDate()));
			sb.append("-");

			Date date = DateUtils.addDays(studentQuery.getCourseDate().getEndDate(), -1);

			sb.append(simpleDateFormat.format(date));
			sb.append("</strong>");
			sb.append("，");
		}

		/*
		 * if (studentQuery.hasLearnStatus()) { sb.append("在读状态：");
		 * 
		 * for (LearnStatus leanStatus : studentQuery.getLearnStatus()) { switch
		 * (leanStatus) { case Finished: sb.append("已结课,"); break; case
		 * Learning: sb.append("在读中,"); break; case Freeze: sb.append("已冻结,");
		 * break; default: break; } } }
		 */
		if (studentQuery.hasSignDate()) {
			sb.append("报名时间：");

			sb.append("<strong>");

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
			sb.append(simpleDateFormat.format(studentQuery.getSignDate().getStartDate()));
			sb.append("-");

			Date date = DateUtils.addDays(studentQuery.getSignDate().getEndDate(), -1);

			sb.append(simpleDateFormat.format(date));

			sb.append("</strong>");
			sb.append("，");
		}

		if (studentQuery.hasTutor()) {
			sb.append("由");

			for (String tutorId : studentQuery.getTutor()) {
				User user = findUser(tutors, tutorId);

				sb.append("<strong>");
				sb.append(user.getName());
				sb.append("</strong>");

				sb.append(",");
			}

			sb.setLength(sb.length() - 1);

			sb.append("辅导，");
		}
		if (sb.length() > 1) {
			sb.setLength(sb.length() - 1);
		}
		return sb;
	}

	private User findUser(Iterable<User> consultants, String consultantId) {
		for (User user : consultants) {
			if (user.getId().equals(consultantId)) {
				return user;
			}
		}

		return new User();
	}

	private StudentQuery buildStudentQuery(FormRow form) {
		String name = form.readString("name");
		String[] learnStatus = form.readStrings("learnStatus");
		String[] consultStarred = form.readStrings("consultStarred");
		String[] tutor = form.readStrings("tutor");
		String[] course = form.readStrings("course");
		String onlyVoid = form.readString("onlyVoid");

		// 报名时间
		Date signStartDate = valueReader.name("signStartDate").defaultValue(null).dateValue("yyyy-MM-dd");
		Date signEndDate = valueReader.name("signEndDate").defaultValue(null).dateValue("yyyy-MM-dd");

		// 开始上课时间
		Date startDate = valueReader.name("startDate").defaultValue(null).dateValue("yyyy-MM-dd");
		Date endDate = valueReader.name("endDate").defaultValue(null).dateValue("yyyy-MM-dd");

		StudentQuery studentQuery = new StudentQuery();

		if (StringUtils.isNotBlank(onlyVoid)) {
			studentQuery.setOnlyVoid(true);
		}

		// 用户名
		if (StringUtils.isNotBlank(name)) {
			studentQuery.setName(name.trim());
		}
		// 学习状态
		if (learnStatus.length > 0) {
			LearnStatus[] learnStatuss = new LearnStatus[learnStatus.length];

			for (int i = 0; i < learnStatuss.length; i++) {
				LearnStatus status = LearnStatus.valueOf(learnStatus[i]);
				learnStatuss[i] = status;
			}

			studentQuery.addLearnStatus(learnStatuss);
		}
		// 咨询师关注
		if (consultStarred.length > 0) {
			boolean[] consultStarreds = new boolean[consultStarred.length];

			for (int i = 0; i < consultStarreds.length; i++) {
				boolean starred = consultStarred[i].equals("true") ? true : false;
				consultStarreds[i] = starred;
			}

			studentQuery.addConsultStarred(consultStarreds);
		}

		// 辅导员筛选
		if (tutor.length > 0) {
			studentQuery.addTutor(tutor);
		}

		// 课程筛选
		if (course.length > 0) {
			studentQuery.addCourse(course);
		}

		// 报名时间
		if (signStartDate != null && signEndDate != null) {
			signEndDate = DateUtils.addDays(signEndDate, 1);

			TimePair timePair = new TimePair();
			timePair.setStartDate(signStartDate);
			timePair.setEndDate(signEndDate);

			studentQuery.setSignDate(timePair);
		}

		// 开始上课时间
		if (startDate != null && endDate != null) {
			endDate = DateUtils.addDays(endDate, 1);

			TimePair timePair = new TimePair();
			timePair.setStartDate(startDate);
			timePair.setEndDate(endDate);

			studentQuery.setCourseDate(timePair);
		}
		return studentQuery;
	}

	@Operation(result = JSON)
	public String doStarredConsult() {
		String id = form.readString("id");

		consultantService.starredConsult(id);

		setJson(JsonResultBuilder.success(true).msg("关注学员成功").json());

		return JSON;
	}

	@Operation(result = JSON)
	public String doUnStarredConsult() {
		String id = form.readString("id");

		consultantService.unStarredConsult(id);

		setJson(JsonResultBuilder.success(true).msg("取消关注学员").json());
		return JSON;
	}

	@Operation(result = FILL, operationText = "列出公共池中的学员")
	public String listFreeStudent() {

		Pageable paginations = getPageable();

		Page<Student> students = studentService.findConsultUnstarred(paginations);
		put("students", students);

		put(PAGINATIONS, new Paginations(students));

		return FILL;
	}

	@Operation(result = FILL, operationText = "列出在跟踪的学员")
	public String listStarredStudent() {

		Pageable paginations = getPageable();

		Page<Student> students = studentService.findConsultStarred(paginations);
		put("students", students);

		put(PAGINATIONS, new Paginations(students));

		return FILL;
	}

	@Operation(result = FILL, operationText = "咨询师饱和度报表")
	public String reportSignedStudent() {
		ArrayList<ConsultantSignedReport> reports = consultantService.reportSignedStudent();

		put("reports", reports);

		return FILL;
	}

	@Operation(result = FILL, operationText = "咨询师饱和度报表")
	public String reportStarredStudent() {
		Map<User, Long> reports = consultantService.reportStarredStudent();

		put("reports", reports);
		put("users", reports.keySet());

		return FILL;
	}

	@Autowired
	ConsultantService consultantService;

	@Operation(result = FILL, operationText = "列出单个咨询师在跟踪的学员")
	public String listStarredStudentByConsultant() {
		String id = form.readString("id");

		Iterable<Student> students = consultantService.listStarredStudentByConsultant(id);

		put("students", students);
		return FILL;
	}

	@Autowired
	StudentService studentService;

	String local = "20";

	@Autowired
	ISeqService seqService;

	public String createStudentNo() {
		String day = new SimpleDateFormat("yyyyMMdd").format(new Date());

		long no = seqService.next("student.no" + day);

		return local + day + no;
	}

	private double rate = -1;

	// 注册课程使用信息
	private String[] ccnames;

	private int day = 30;

	public void setRate(double rate) {
		this.rate = rate;
	}

	public double getRate() {
		return rate;
	}

	public void setCcnames(String[] ccnames) {
		this.ccnames = ccnames;
	}

	public String[] getCcnames() {
		return ccnames;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

}
